#pragma once
class TMesh;
class SndBuffer;
class PRender;
class PInit;
class MTech;
class MTex;
class AComponent;
class Actor;
class ActorFactory;
class Camera;
class Kismet;
class Level;
class LightActor;
class Mesh;
class PAffect;
class Particle;
class PGroup;
class Sequence;
class SndActor;
class StaticModel;
class TBatchGroup;
class Terrain;
class TTile;
class World;
extern EventDef* _evt_TestEvent0;
extern EventDef* _evt_TestEvent1;
extern EventDef* _evt_SequenceBegin;
extern EventDef* _evt_SequenceEnd;
////////////Enum EPartiDirection////////////
enum EPartiDirection
{
	PD_Target,
	PD_BaseDir,
	PD_Random,
	PD_UpUnitZ,
};
EnumDef* EPartiDirection_RTTI();
////////////Enum ESoundFade////////////
enum ESoundFade
{
	SF_Ambient,
	SF_Ambient_Fade,
	SF_Point,
};
EnumDef* ESoundFade_RTTI();
////////////class AComponent////////////
class AComponent: public Obj
{
	Base_DeclareObj( AComponent, Obj);
public:
	// CppCode
	virtual void OnInitScene();
	virtual void OnDeInitScene();
	virtual void OnTick( size_t frameNum, float gameTime, float delTime);
};
////////////class Actor////////////
class Actor: public Obj, public IOctreeObj
{
	Base_DeclareObj( Actor, Obj);
public:
	// Actor
	s32_t mActorID;
	// Tick
	bool mTickIsActive;
	// Trans
	vec3_t mTransPos;
	rot4_t mTransRot;
	s32_t mTransScale;
	// AI
	bool mAIDelete;
	// Data def
	static PropDef* _dataDef_mTickIsActive;
	static PropDef* _dataDef_mTransPos;
	static PropDef* _dataDef_mTransRot;
	static PropDef* _dataDef_mTransScale;
	// CppCode
	virtual ClassDef* _editorexpFinalCls();
	virtual inline bool IsTrackable()
	{
		return false;
	}
	virtual DString ViewName();
	virtual void OnActiveChanged();
	inline void  SetActive( bool val)
	{
		mTickIsActive = val;
		OnActiveChanged();
	}
	// IOctreeObj
	virtual inline Obj* Octree_GetObj()
	{
		return this;
	}
	inline Ogre::AxisAlignedBox const& GetWorldBox()
	{
		return mWorldAABB;
	}
	// frame update //////////begin
	// step ,1
	// update RootNode Pos
	virtual void OnTick( u32_t frameNum, f32_t gameTime, f32_t delTime);
	// step ,2
	virtual void OnNodeUpdated();
	// step ,3
	virtual void UpdateBoundingBox();
	// step ,4
	virtual void OnCameraVisible(  Ogre::Camera* cam);
	// frame update //////////end
	Level* mLevel;
	void UpdateComponentList();
	TArray<AComponent*> mCompList;
	Ogre::AxisAlignedBox mWorldAABB;
	// Scene
	Ogre::SceneNode* mRootNode;
	virtual bool IsMovable();
	void OnSceneManaged( Level* );
	void OnSceneUnManaged();
	// Data
	void OnDataModified( PropDef* def);
};
////////////class ActorFactory////////////
class ActorFactory: public Actor
{
	Ins_DeclareObj( ActorFactory, Actor);
public:
	void NewActor( s32_t & id);
	void AddTemplate( s32_t id);
	void ClearAll();
};
////////////class Camera////////////
class Camera: public Actor
{
	Ins_DeclareObj( Camera, Actor);
public:
	// Ctrl
	bool mCtrlSync;
	// Data def
	static PropDef* _dataDef_mCtrlSync;
	// CppCode
	virtual inline bool IsTrackable()
	{
		return true;
	}
	void OnInitScene();
	void OnDeInitScene();
 	virtual void OnTick( u32_t numFrame, f32_t gameTime, f32_t delTime);
};
////////////class Kismet////////////
class Kismet: public Obj
{
	Ins_DeclareObj( Kismet, Obj);
public:
	// CppCode
	s32_t	mCtrlActorID;
	Level*	mLevel;
	// save and load Datas, codes 
	virtual void	OnStream( Pack*);
	DataPack		mVarDatas;
	TArray< u8_t> mExecuteCode;
	struct SleepCode_t
	{
		float Time;
		u16_t Code;
	};
	TArray< SleepCode_t>	mSleepCodes;
	u16_t mCurrCodePos;
};
////////////class Level////////////
class Level: public Obj
{
	Ins_DeclareObj( Level, Obj);
public:
	// Actor
	TArray< Actor::Ptr > mActorList;
};
////////////class LightActor////////////
class LightActor: public Actor
{
	Ins_DeclareObj( LightActor, Actor);
public:
	// Light
	Ogre::Light::LightTypes mLightType;
	bool mLightIsStatic;
	bool mLightIsOn;
	bool mLightIsAffectDynamicObject;
	// Color
	color4_t mColorDiffuse;
	color4_t mColorSpecular;
	// Attenuation
	f32_t mAttenuationRange;
	f32_t mAttenuationConstant;
	f32_t mAttenuationLinear;
	f32_t mAttenuationQuadric;
	// Angle
	f32_t mAngleOutter;
	f32_t mAngleInner;
	f32_t mAngleFalloff;
	// CppCode
	Ogre::Light::LightTypes m_type;
	bool IsAffect( Ogre::AxisAlignedBox const& box);
	Ogre::AxisAlignedBox const& GetWorldBounding();
	bool m_boundingDirty;
	void Do_Bounding();
	void NotifyActorMoved();
	void OnDataModified( PropDef* def);
};
////////////class MTex////////////
class MTex: public Res
{
	Ins_DeclareObj( MTex, Res);
public:
	// Size
	u32_t mSizeWidth;
	u32_t mSizeHeight;
	// CppCode
	Ogre::Texture* GetTexure();
	u32_t GetWidth();
	u32_t GetHeight();
	DString TextureFileName();
	void LoadTexture();
};

////////////struct MTexUnit////////////
struct MTexUnit
{
	typedef TArray< MTexUnit > Array;
	// Color
	Ogre::LayerBlendOperationEx mColorOpera;
	Ogre::LayerBlendSource mColorSrc1;
	Ogre::LayerBlendSource mColorSrc2;
	f32_t mColorArg1;
	f32_t mColorArg2;
	f32_t mColorFactor;
	// Alpha
	Ogre::LayerBlendOperationEx mAlphaOpera;
	Ogre::LayerBlendSource mAlphaSrc1;
	Ogre::LayerBlendSource mAlphaSrc2;
	f32_t mAlphaArg1;
	f32_t mAlphaArg2;
	f32_t mAlphaFactor;
	// Filter
	Ogre::FilterOptions mFilterMin;
	Ogre::FilterOptions mFilterMag;
	Ogre::FilterOptions mFilterMip;
	// Addressing
	Ogre::TextureUnitState::TextureAddressingMode mAddressingU;
	Ogre::TextureUnitState::TextureAddressingMode mAddressingV;
	Ogre::TextureUnitState::TextureAddressingMode mAddressingW;
	// Scroll
	f32_t mScrollU;
	f32_t mScrollV;
	// Scale
	f32_t mScaleU;
	f32_t mScaleV;
	// Coord
	u32_t mCoordIndex;
	// Maps
	TArray< MTex::Ptr > mMapsTexMaps;
	//RTTI
	static StructDef* RTTI();
};

////////////struct MPass////////////
struct MPass
{
	typedef TArray< MPass > Array;
	// Color
	color4_t mColorAmbient;
	color4_t mColorDiffuse;
	color4_t mColorSpecular;
	color4_t mColorEmissive;
	Ogre::TrackVertexColourEnum mColorVCUsage;
	// Blend
	Ogre::SceneBlendFactor mBlendSource;
	Ogre::SceneBlendFactor mBlendDest;
	// Light
	bool mLightOn;
	// Depth
	bool mDepthCheck;
	bool mDepthWrite;
	Ogre::CompareFunction mDepthFunc;
	f32_t mDepthConstant;
	f32_t mDepthSlopeScale;
	f32_t mDepthPerIteration;
	// Fog
	bool mFogOverride;
	Ogre::FogMode mFogFogMode;
	color4_t mFogColor;
	f32_t mFogStart;
	f32_t mFogEnd;
	f32_t mFogDensity;
	// AlphaReject
	Ogre::CompareFunction mAlphaRejectFunc;
	s32_t mAlphaRejectVal;
	bool mAlphaRejectToCoverageEnabled;
	// TextUnit
	MTexUnit mTextUnit0;
	MTexUnit mTextUnit1;
	//RTTI
	static StructDef* RTTI();
};
////////////class MTech////////////
class MTech: public Obj
{
	Ins_DeclareObj( MTech, Obj);
public:
	// Cull
	Ogre::CullingMode mCullMode;
	// Pass
	MPass::Array mPassPasses;
	// CppCode
public:
	Ogre::Technique* GetCoreTech();
	Ogre::MaterialPtr const& GetCoreMat();
private:
	void BuildCoreMaterial();
	bool mNeedBuild;
	Ogre::Technique* mCoreTech;
	Ogre::MaterialPtr mCoreMaterial;
};

////////////struct SubMesh////////////
struct SubMesh
{
	typedef TArray< SubMesh > Array;
	// Setting
	bool mSettingIsCollision;
	bool mSettingVisible;
	struct Vertex
	{
		vec3_t Pos;
		vec3_t Normal;
		vec2_t DiffuseUV;
	};
	TArray< Vertex> mVertexData;
	TArray< u16_t > mIndexData;
	void BindVertexBuffer0( Ogre::VertexData& vertData);
	void InitRenderData();
	Ogre::HardwareIndexBufferSharedPtr mHwIB;
	Ogre::HardwareVertexBufferSharedPtr mHwVB;
	Ogre::AxisAlignedBox mLocalBound;
	//RTTI
	static StructDef* RTTI();
};
////////////class Mesh////////////
class Mesh: public Res
{
	Ins_DeclareObj( Mesh, Res);
public:
	// Subs
	SubMesh::Array mSubsSubAry;
	// CppCode
	s32_t NumColorVertex();
	void LoadMesh();
	bool mLoaded;
};
////////////class PAffect////////////
class PAffect: public Obj
{
	Base_DeclareObj( PAffect, Obj);
public:
	// CppCode
	virtual void Apply( PData* data, float deltaTime, float lifePos) = 0;
	PGroup* mOwnerGrp;
};
////////////class Particle////////////
class Particle: public Actor
{
	Ins_DeclareObj( Particle, Actor);
public:
};
////////////class PInit////////////
class PInit: public Obj
{
	Base_DeclareObj( PInit, Obj);
public:
	// CppCode
	virtual void InitParti( PData*) = 0;
	PGroup* mOwnerGrp;
};
////////////class PRender////////////
class PRender: public Obj
{
	Base_DeclareObj( PRender, Obj);
public:
	// CppCode
	virtual bool IsReady() = 0;
	virtual void PushToRenderQuene() = 0;
	float mDistanceOffset;
	PGroup* mOwnerGrp;
};
////////////class PGroup////////////
class PGroup: public Obj
{
	Base_DeclareObj( PGroup, Obj);
public:
};
////////////class Sequence////////////
class Sequence: public Actor
{
	Ins_DeclareObj( Sequence, Actor);
public:
	void Play();
	void Stop();
	// CppCode
	struct TimeTag
	{
		float Time;
		s32_t Index;
	};
	struct Track
	{
		Actor* mTrackActor;
		size_t mTrackActorID;
		TArray< TimeTag > m_keyIndex;
		Ogre::SimpleSpline m_transSpline;
		Ogre::RotationalSpline m_rotSpline;
	};
	TArray< Track > mActorTracks;
	TArray< TimeTag > mTimeTags;
	void OnTick( u32_t frameNum, f32_t gameTime, f32_t delTime);
	f32_t mMoveLength;
	f32_t mPlayedTime;
};
////////////class SndBuffer////////////
class SndBuffer: public Res
{
	Ins_DeclareObj( SndBuffer, Res);
public:
	// AL
	s32_t mALFormat;
	s32_t mALFrequency;
	// Play
	bool mPlayLoop;
	// CppCode
	inline u32_t GetBind()
	{
		if( mBindBufID == null_index)
		{
			LoadData();
		}
		return mBindBufID;
	}
	u32_t mBindBufID;
	void LoadData();
};
////////////class SndActor////////////
class SndActor: public Actor
{
	Ins_DeclareObj( SndActor, Actor);
public:
	// Src
	SndBuffer::Ptr mSrcBuffer;
	// Fade
	f32_t mFadeVolume;
	f32_t mFadeRadius;
	f32_t mFadePow;
	ESoundFade mFadeFade;
	void Play();
	void Stop();
	// CppCode
	virtual void OnTick( size_t frameNum, float gameTime, float delTime);
	void UpdateDistanceModel();
	void _allocALData();
	void _freeALData();
};

////////////struct SubStaticModel////////////
struct SubStaticModel: public Primitive
{
	typedef TArray< SubStaticModel > Array;
	Ogre::VertexData		mVertexData;
	Ogre::IndexData			mIndexData;
	Ogre::RenderOperation	mRenderOp;
	Ogre::Technique*		mDrawTech;
	SubMesh*				mSubMesh;
	StaticModel*			mModelActor;
	void InitRenderData( StaticModel* model, SubMesh* subMesh);
	void Draw( DrawPrimitiveCall const& , Ogre::Camera* camera);
	Ogre::HardwareVertexBufferSharedPtr mDiffuseVB;
	void UpdataWorldBound();
	void CameraVisible( Ogre::Camera* camera);
	Ogre::AxisAlignedBox m_worldBound;
	//RTTI
	static StructDef* RTTI();
};
////////////class StaticModel////////////
class StaticModel: public Obj
{
	Ins_DeclareObj( StaticModel, Obj);
public:
};
////////////class TMesh////////////
class TMesh: public Obj, public IOctreeObj, public Primitive
{
	Base_DeclareObj( TMesh, Obj);
public:
	// Geom
	s32_t mGeomIndex;
	// CppCode
	Ogre::DataStreamPtr OpenData();
	Ogre::VertexData mVertexData;
	Ogre::IndexData mIndexData;
	Ogre::RenderOperation mRenderOp;
	ds_t _resName( ds_t const& resDefName);
	//////////////////////IOctreeObj//////////////////////
	void OnNodeUpdated();
	void UpdateBoundingBox();	
	Ogre::AxisAlignedBox const& GetWorldBox();
	Obj* Octree_GetObj();
	Ogre::AxisAlignedBox mStaticWorldBox;
	Ogre::SceneNode* mSceneNode;
	void Draw( DrawPrimitiveCall const& , Ogre::Camera* camera);
};
////////////class TBatchGroup////////////
class TBatchGroup: public TMesh
{
	Ins_DeclareObj( TBatchGroup, TMesh);
public:
	// CppCode
	void OnCameraVisible( Ogre::Camera*);
};
////////////class Terrain////////////
class Terrain: public Actor
{
	Ins_DeclareObj( Terrain, Actor);
public:
};
////////////class TTile////////////
class TTile: public TMesh
{
	Ins_DeclareObj( TTile, TMesh);
public:
	// CppCode
	void OnCameraVisible( Ogre::Camera*);
};
////////////class World////////////
class World: public Obj
{
	Ins_DeclareObj( World, Obj);
public:
	// Sunlight
	vec3_t mSunlightDir;
	color4_t mSunlightDiffuse;
	color4_t mSunlightAmbient;
	// Fog
	color4_t mFogColor;
	f32_t mFogBegin;
	f32_t mFogEnd;
	f32_t mFogDensity;
	// CppCode
	TArray< Level::Ptr> mLevels;
};
////////////Framework RTTI Init////////////
void Init_Framework_Class();
